home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Various / DevDisk 65 (1989)(DevWare PD).zip / DevDisk 65 (1989)(DevWare PD).adf / ifflib / ShowIFF / ShowIFF.c < prev    next >
C/C++ Source or Header  |  1990-07-11  |  22KB  |  624 lines

  1. /*************************************************************************
  2. **                                                                      **
  3. **  ShowIFF - a comfortable IFF file viewer for CLI and WorkBench       **
  4. **                                                                      **
  5. **  All known formats (including Overscan, HAM, HalfBrite, SHAM) are    **
  6. **  supported. If a picture is larger than the screen, you may use the  **
  7. **  mouse to scroll around (If you have enough CHIP memory...)          **
  8. **                                                                      **
  9. **  This program and iff.library by:     Chris Weber                    **
  10. **                                       Bruggerweg 2                   **
  11. **                                       CH-8037 Zürich                 **
  12. **                                       SWITZERLAND                    **
  13. **                                       (BIX: chw)                     **
  14. **                                                                      **
  15. **  Any suggestions or bug reports are welcome!                         **
  16. **                                                                      **
  17. **************************************************************************
  18. **                                                                      **
  19. **  This program is in the Public Domain. Use it at your own risk.      **
  20. **                                                                      **
  21. **  Requirements:  - arp.library V39+                                   **
  22. **                 - iff.library V18+                                   **
  23. **                                                                      **
  24. **  To compile:    - Lattice C compiler V5.04 or above (use 32bit ints) **
  25. **                 - The file 'arpstartup.o' (My ARP startup module)    **
  26. **                 - The file 'arpglue.lib' for Printf etc.             **
  27. **                                                                      **
  28. **************************************************************************
  29. **                                                                      **
  30. **  WorkBench usage:                                                    **
  31. **  ---------------                                                     **
  32. **                                                                      **
  33. **  Select all pictures you wish to see while pressing the SHIFT key,   **
  34. **  then double-click on the ShowIFF icon.                              **
  35. **  You can also set the picture's default tool to 'ShowIFF' using the  **
  36. **  WorkBench 'Info' feature.                                           **
  37. **  If you wish to display all the pictures in a drawer, select the     **
  38. **  drawer and then the ShowIFF icon. This works even with disk icons!  **
  39. **  If a drawer or disk contains another drawer, the pictures in that   **
  40. **  drawer will also be displayed.                                      **
  41. **                                                                      **
  42. **                                                                      **
  43. **  CLI usage:                                                          **
  44. **  ---------                                                           **
  45. **                                                                      **
  46. **  ShowIFF [files] [DELAY delay in seconds] [LOOP] [ALL] [NOBREAK]     **
  47. **  [NOOVERSCAN]                                                        **
  48. **                                                                      **
  49. **  Example:  ShowIFF Lo-Res/Pic* Hi-Res/foo RAM:*.pic DELAY 5 ALL      **
  50. **                                                                      **
  51. **  [files] can be any number of file names, directories or disk names. **
  52. **     All of the ARP wildcards can be used. (?,*,#?,...)               **
  53. **                                                                      **
  54. **  [DELAY] specifies the delay between two pictures in seconds. If not **
  55. **     specified, this is set to infinity. Note that you can always go  **
  56. **     to the next picture by pressing the left mouse button.           **
  57. **                                                                      **
  58. **  [LOOP] if specified, repeatedly displays all the pictures, which is **
  59. **     useful for creating slide-shows or other demos.                  **
  60. **                                                                      **
  61. **  [ALL] if specified, pictures in sub-directories will also be        **
  62. **     displayed.                                                       **
  63. **                                                                      **
  64. **  [NOBREAK] disabled the breaking features described below            **
  65. **                                                                      **
  66. **  [NOOVERSCAN] display all pictures in normal mode, and never in      **
  67. **     overscan. This is useful if you want to see every pixel...       **
  68. **                                                                      **
  69. **                                                                      **
  70. **  Keys and mouse-buttons:                                             **
  71. **  ----------------------                                              **
  72. **                                                                      **
  73. **  While a picture is displayed, you can                               **
  74. **                                                                      **
  75. **  - press the left mouse button, which will display the next picture  **
  76. **                                                                      **
  77. **  - press the right mouse button, which will abort the program        **
  78. **                                                                      **
  79. **  - press Ctrl-C (if the ShowIFF window or the CLI window is active)  **
  80. **       which will abort the ShowIFF program                           **
  81. **                                                                      **
  82. **  - press Ctrl-E (if the ShowIFF window or the CLI window is active)  **
  83. **       which will quit the current directory and return to the        **
  84. **       parent-directory (only in conjunction with the 'ALL' option)   **
  85. **                                                                      **
  86. **  - move the mouse, the picture will scroll if it is larger than the  **
  87. **       screen. Note that HAM pictures may have distortions on the     **
  88. **       left side. This is a hardware limitation of the HAM mode.      **
  89. **                                                                      **
  90. **************************************************************************
  91. **                                                                      **
  92. **    Modification History:                                             **
  93. **    --------------------                                              **
  94. **                                                                      **
  95. **    15-Oct-87  CHW  V1.0   Created this file!                         **
  96. **    30-Jun-88  CHW  V1.4   Directory scan fixed for FFS, cleaned up   **
  97. **    16-Nov-88  CHW  V1.5   Overscan implemented                       **
  98. **    28-Nov-88  CHW  V1.6   Minimal screen size is now 64x64 pixels    **
  99. **    02-Jan-89  CHW  V1.7   Double-buffering implemented               **
  100. **    25-Sep-89  CHW  V2.01  Changed to Lattice C and ARP library       **
  101. **    27-Sep-89  CHW  V2.02  Screen scrolling implemented               **
  102. **    22-Nov-89  CHW  V2.03  Rejects Non-ILBM files correctly           **
  103. **    21-Feb-90  CHW  V2.04  'NoMemForGfx' bug fixed, overscan fixed    **
  104. **    28-Feb-90  CHW  V2.10  SHAM support code added                    **
  105. **    14-Mar-90  CHW  V2.11  Memory fragmentation workaround, cleanup   **
  106. **    08-Apr-90  CHW  V2.12  Pics with more than 6 planes don't guru    **
  107. **                                                                      **
  108. *************************************************************************/
  109.  
  110. #include <proto/exec.h>
  111. #include <exec/memory.h>
  112. #include <arp/arpbase.h>
  113. #include <proto/graphics.h>
  114. #include <proto/intuition.h>
  115. #include <graphics/gfxbase.h>
  116. #include <graphics/gfxmacros.h>
  117. #include <hardware/custom.h>
  118. #include <libraries/iff.h>        /* Not an official CBM file (yet?:-) */
  119. #include <workbench/startup.h>
  120. #include <string.h>
  121.  
  122. #define MIN(a,b) ((a)<(b)?(a):(b))
  123. #define MAX(a,b) ((a)>(b)?(a):(b))
  124. #define reg register            /* My favorite alias */
  125.  
  126. struct MyAnchor
  127. {
  128.     struct AnchorPath APath;
  129.     char   FullPath[255];        /* cheap way to extend ap_Buf[] */
  130. };
  131.  
  132. struct Picture
  133. {
  134.     struct Screen *Screen;        /* The picture's screen */
  135.     struct Window *Window;        /* The invisible window for mouse handling */
  136.     struct BitMap BitMap;        /* CustomBitMap, may be larger than screen */
  137.     WORD MaxX0,MaxY0;            /* Scrolling limits */
  138. };
  139.  
  140. char StdWindowName[] = "CON:0/12/640/82/ShowIFF V2.12  08-Apr-90 by Christian A. Weber";
  141. char CLI_Template[]  = "Patterns/...,D=DELAY/k,L=LOOP/s,ALL/s,NB=NOBREAK/s,NO=NOOVERSCAN/s";
  142. char CLI_Help[]      = "ShowIFF V2.12 08-Apr-90 by Christian A. Weber\n"
  143.                         "Usage: ShowIFF [files or patterns] [DELAY delay] [LOOP] [ALL]\n"
  144.                         "\t\t[NOBREAK] [NOOVERSCAN]";
  145.  
  146. #define ARG_PATTERN    0                /* Argument numbers for GADS() */
  147. #define ARG_DELAY      1
  148. #define ARG_LOOP       2
  149. #define ARG_ALL        3
  150. #define ARG_NOBREAK    4
  151. #define ARG_NOOVERSCAN 5
  152. #define ARG_INVALID    6
  153. #define NUMARGS        (ARG_INVALID+1)
  154.  
  155. extern void exit(LONG);                    /* My startup code's exit function */
  156. extern struct Library *ArpBase;            /* Also used for DOS functions */
  157. extern struct Library *IntuitionBase;    /* Opened by ArpStartup */
  158. extern struct GfxBase *GfxBase;            /* Opened by ArpStartup */
  159. struct Library *IFFBase;                /* That's the big one! */
  160. extern struct Custom __far custom;        /* For SSHAM copper list */
  161.  
  162. BOOL WorkBench;
  163. LONG WBDelay=3145728;            /* keep window open for 3 seconds*/
  164.  
  165. struct Picture pic1,pic2;        /* 2 pictures for double-buffering */
  166. IFFFILE ifffile;
  167. WORD *emptysprite;
  168.  
  169. LONG delay      = 0x100000;        /* Default parameters for WB */
  170. BOOL loop       = FALSE;
  171. BOOL all        = TRUE;
  172. BOOL nobreak    = FALSE;
  173. BOOL overscan   = TRUE;
  174.  
  175. /*************************************************************************/
  176.  
  177. void ZeroMem(reg UBYTE *adr,reg LONG len)
  178. {
  179.     while(--len>=0) *adr++=0;
  180. }
  181.  
  182. /*************************************************************************/
  183. /* Free all planes of a bitmap */
  184.  
  185. void FreeBitMap(reg struct BitMap *bm)
  186. {
  187.     reg LONG planesize=bm->BytesPerRow*(bm->Rows+8),i;
  188.  
  189.     for(i=0; i<bm->Depth; ++i)
  190.         if(bm->Planes[i])
  191.         {
  192.             FreeMem(bm->Planes[i],planesize);
  193.             bm->Planes[i]=0;
  194.         }
  195. }
  196.  
  197. /*************************************************************************/
  198. /* Initialize a BitMap structure and allocate CHIP memory for the planes */
  199.  
  200. BOOL AllocBitMap(reg struct BitMap *bm,LONG d,LONG w,LONG h)
  201. {
  202.     reg LONG planesize,i;
  203.  
  204.     InitBitMap(bm,d,w,h);
  205.     planesize=bm->BytesPerRow*(bm->Rows+8);
  206.  
  207.     for(i=0; i<d; ++i)
  208.         if(!(bm->Planes[i]=AllocMem(planesize,MEMF_CHIP|MEMF_CLEAR)))
  209.         {
  210.             FreeBitMap(bm);
  211.             return FALSE;
  212.         }
  213.     return TRUE;
  214. }
  215.  
  216. /*************************************************************************/
  217. /* Adjust the X/Y position of a screen for correct overscan display */
  218.  
  219. void SetOverscan(struct Screen *screen)
  220. {
  221.     reg WORD rows,x=screen->Width,y=screen->Height;
  222.     reg struct ViewPort *vp=&(screen->ViewPort);
  223.  
  224.     rows = GfxBase->NormalDisplayRows; if(rows>300) rows>>=1;
  225.     x -= 320;  if(vp->Modes & HIRES) x -= 320;
  226.     y -= rows; if(vp->Modes & LACE)  y -= rows;
  227.     x >>=1; if(x<0) x=0; y >>=1; if(y<0) y=0; if(y>40) y=40;
  228.  
  229.     if(vp->Modes & HAM)    /* Correct overscan HAM color distortions */
  230.     {
  231.         if(GfxBase->ActiView->DxOffset-x < 96)
  232.             x=GfxBase->ActiView->DxOffset-96;
  233.     }
  234.     vp->DxOffset = -x; vp->DyOffset = -y;
  235.     MakeScreen(screen); RethinkDisplay();
  236. }
  237.  
  238. /*************************************************************************/
  239. /* Make SHAM copper list if this is an SHAM picture */
  240.  
  241. void MakeSHAM(struct Picture *pic)
  242. {
  243.     reg LONG i,j,step=(pic->Screen->ViewPort.Modes&LACE)?2:1;
  244.     reg WORD copx=GfxBase->ActiView->DxOffset+pic->Screen->Width;
  245.     reg struct UCopList *ucop=AllocMem(sizeof(struct UCopList),MEMF_CLEAR);
  246.     reg struct SHamChunk
  247.     {
  248.         struct Chunk    Chunk;
  249.         UWORD            Version;
  250.         UWORD            Colors[1024][16];
  251.     } *shamck;
  252.  
  253.     if(ucop && (shamck=FindChunk(ifffile,ID_SHAM)))
  254.     {
  255.         if(shamck->Version == 0)
  256.         {
  257.             Printf("SHAM ");
  258.             for(i=1; i<MIN(pic->Screen->Height,shamck->Chunk.ckSize>>5); ++i)
  259.             {
  260.                 CWAIT(ucop,(i-1)*step,(UWORD)((copx>>1)%(UWORD)228))
  261.                 for(j=1; j<16; ++j) CMOVE(ucop,custom.color[j],shamck->Colors[i][j])
  262.             }
  263.             CEND(ucop)
  264.             pic->Screen->ViewPort.UCopIns = ucop; RemakeDisplay();
  265.         }
  266.         else Printf("Unsupported SHAM mode: %ld",(LONG)shamck->Version);
  267.     }
  268. }
  269.  
  270. /*************************************************************************/
  271. /* Free a picture (that is a window, screen and a custom BitMap) */
  272.  
  273. void ClosePicture(reg struct Picture *pic)
  274. {
  275.     if(pic->Window)
  276.     {
  277.         ScreenToBack(pic->Screen);
  278.         ClearPointer(pic->Window);
  279.         CloseWindow(pic->Window);
  280.         pic->Window=0;
  281.     }
  282.  
  283.     if(pic->Screen)
  284.     {
  285.         CloseScreen(pic->Screen);
  286.         pic->Screen=0;
  287.     }
  288.  
  289.     FreeBitMap(&pic->BitMap);
  290.     RemakeDisplay();    /* remake copperlist to increase MEMF_LARGEST */
  291. }
  292.  
  293. /*************************************************************************/
  294. /* Allocate a picture (Allocate custom BitMap, open screen and window) */
  295.  
  296. BOOL OpenPicture(reg struct Picture *pic,reg struct BitMapHeader *bmhd)
  297. {
  298.     reg WORD xov=64,yov=40;        /* Maximal overscan values for LoRes */
  299.     struct NewScreen ns;
  300.     struct NewWindow nw;
  301.     UWORD colortable[512];
  302.  
  303.     ClosePicture(pic);
  304.  
  305.     ZeroMem((UBYTE *)&ns,sizeof(ns));
  306.     ZeroMem((UBYTE *)&nw,sizeof(nw));
  307.  
  308.     ns.Width        = 320;                            /* Minimal width */
  309.     ns.Height       = GfxBase->NormalDisplayRows;    /* Minimal height */
  310.     ns.Depth        = MAX(bmhd->nPlanes,1);
  311.     ns.ViewModes    = (UWORD)GetViewModes(ifffile);
  312.     ns.Type         = CUSTOMSCREEN|CUSTOMBITMAP|SCREENQUIET|SCREENBEHIND;
  313.     ns.CustomBitMap = &pic->BitMap;
  314.  
  315.     if(ns.ViewModes & HIRES) { ns.Width  <<= 1; xov <<= 1; }
  316.     if(ns.ViewModes & LACE)  { ns.Height <<= 1; yov <<= 1; }
  317.  
  318.     if(overscan)
  319.     {
  320.         if((bmhd->w > ns.Width) && (bmhd->w <= (ns.Width+xov)))
  321.             ns.Width = bmhd->w;
  322.  
  323.         if((bmhd->h > ns.Height) && (bmhd->h <= (ns.Height+yov)))
  324.             ns.Height = bmhd->h;
  325.     }
  326.  
  327.     if(AllocBitMap(&pic->BitMap,(LONG)bmhd->nPlanes,
  328.                 MAX(bmhd->w,ns.Width),MAX(bmhd->h,ns.Height)))
  329.     {
  330.         if(nw.Screen=pic->Screen=OpenScreen(&ns))
  331.         {
  332.             if(ns.Depth>6)
  333.             {
  334.                 pic->Screen->BitMap.Depth=ns.ViewModes & HIRES ? 4:5;
  335.                 RemakeDisplay();
  336.             }
  337.             nw.Width      = ns.Width;
  338.             nw.Height     = ns.Height;
  339.             nw.IDCMPFlags = MOUSEBUTTONS|MOUSEMOVE|DELTAMOVE;
  340.             nw.Flags      = BACKDROP|BORDERLESS|ACTIVATE|SIMPLE_REFRESH
  341.                                 |NOCAREREFRESH|REPORTMOUSE|RMBTRAP;
  342.             nw.Type       = CUSTOMSCREEN;
  343.  
  344.             if(pic->Window=OpenWindow(&nw))
  345.             {
  346.                 reg long count;
  347.  
  348.                 pic->MaxX0=bmhd->w-ns.Width;
  349.                 pic->MaxY0=bmhd->h-ns.Height;
  350.  
  351.                 SetPointer(pic->Window,emptysprite,1L,16L,0L,0L);
  352.                 if(!(count=GetColorTab(ifffile,colortable)))
  353.                 {
  354.                     /* Provide default colors for pictures without a CMAP */
  355.                     count=2; colortable[0]=0xeca; colortable[1]=0x000;
  356.                 }
  357.                 if(count>32) count = 32; /* Fix old DigiView pictures */
  358.                 LoadRGB4(&(pic->Screen->ViewPort),colortable,count);
  359.                 SetOverscan(pic->Screen);
  360.                 return TRUE;
  361.             }
  362.         }
  363.     }
  364.     ClosePicture(pic);
  365.     return FALSE;
  366. }
  367.  
  368. /*************************************************************************/
  369. /* Close all resources and exit to CLI/WorkBench */
  370.  
  371. void Fail(reg char *reason)
  372. {
  373.     Printf("%s\n",reason);
  374.  
  375.     ClosePicture(&pic1); ClosePicture(&pic2);
  376.  
  377.     if(ifffile)        { CloseIFF(ifffile); ifffile=0; }
  378.     if(emptysprite) { FreeMem(emptysprite,20); emptysprite=0; }
  379.     if(IFFBase)        { CloseLibrary(IFFBase); IFFBase=0; }
  380.  
  381.     if(WorkBench) WaitForChar(Input(),WBDelay);    /* Let them see our text */
  382.     exit(0L);    /* Back to the startup code (important for WorkBench) */
  383. }
  384.  
  385. /*************************************************************************/
  386. /* This gets called if the user hits ^C or sends us a BREAK signal */
  387.  
  388. __stdargs void _abort(void)
  389. {
  390.     Fail("\n***BREAK - ShowIFF terminated.");
  391. }
  392.  
  393. /************************************************************************/
  394. /* That's the big one! Load & display a picture (with mouse-scrolling) */
  395.  
  396. void ShowPicture(reg char *name)
  397. {
  398.     if(!strcmp(name+strlen(name)-5,".info")) return;    /* Skip icons */
  399.     Printf("%s ... ",name);
  400.  
  401.     if(ifffile) CloseIFF(ifffile);
  402.     if(ifffile=OpenIFF(name))
  403.     {
  404.         if(*(((ULONG *)ifffile)+2) == ID_ILBM)
  405.         {
  406.             reg struct BitMapHeader *bmhd;
  407.             if(bmhd=GetBMHD(ifffile))
  408.             {
  409.                 Printf("%ld x %ld x %ld ",bmhd->w,bmhd->h,bmhd->nPlanes);
  410. retry:            if(OpenPicture(&pic1,bmhd))
  411.                 {
  412.                     if(DecodePic(ifffile,&pic1.BitMap))
  413.                     {
  414.                         reg LONG i;
  415.                         reg WORD xoff=0,yoff=0;
  416.  
  417.                         MakeSHAM(&pic1);
  418.                         ScreenToFront(pic1.Screen);
  419.                         ClosePicture(&pic2);
  420.                         for(i=delay*50L; i>=0; --i)
  421.                         {
  422.                             reg struct IntuiMessage *msg;
  423.  
  424.                             WaitTOF();
  425.                             while(msg=(struct IntuiMessage *)GetMsg(pic1.Window->UserPort))
  426.                             {
  427.                                 if(msg->Class == MOUSEMOVE)
  428.                                 {
  429.                                     xoff+=msg->MouseX;
  430.                                     if(xoff>pic1.MaxX0) xoff=pic1.MaxX0;
  431.                                     if(xoff<0) xoff=0;
  432.                                     yoff+=msg->MouseY;
  433.                                     if(yoff>pic1.MaxY0) yoff=pic1.MaxY0;
  434.                                     if(yoff<0) yoff=0;
  435.                                     pic1.Screen->ViewPort.RasInfo->RxOffset=xoff;
  436.                                     pic1.Screen->ViewPort.RasInfo->RyOffset=yoff;
  437.                                     /* ScrollVPort(&pic1.Screen->ViewPort); */
  438.                                     MakeScreen(pic1.Screen); RethinkDisplay();
  439.                                 }
  440.                                 else if(!nobreak)
  441.                                 {
  442.                                     if(msg->Code == SELECTDOWN) goto showend;
  443.                                     else if(msg->Code == MENUDOWN) _abort();
  444.                                 }
  445.                                 ReplyMsg((struct Message *)msg);
  446.                             }
  447.                             if(!nobreak) CheckAbort(_abort);
  448.                         }
  449. showend:                pic2=pic1; ZeroMem((UBYTE *)&pic1,sizeof(pic1));
  450.                         Puts(" - Done");
  451.                     }
  452.                     else
  453.                     {
  454.                         ClosePicture(&pic1);
  455.                         Printf("- Decode error: %ld\n",IFFError());
  456.                     }
  457.                 }
  458.                 else if(pic2.Window)
  459.                 {
  460.                     ClosePicture(&pic2); goto retry;
  461.                 }
  462.                 else Puts("- Can't open screen!");
  463.             }
  464.             else Printf("- Mangled IFF file (%ld)\n",IFFError());
  465.         }
  466.         else Puts("- not an ILBM file!");
  467.     }
  468.     else Puts("- not an IFF file!");
  469. }
  470.  
  471. /************************************************************************/
  472. /* Expand a pattern and call ShowPicture() for each matching file */
  473.  
  474. void ShowPattern(char *pathname)
  475. {
  476.     reg BPTR file;
  477.     char buf[256];
  478.  
  479.     if(PreParse(pathname,buf))    /* TRUE if name contains any wildcards */
  480.     {
  481.         reg struct MyAnchor *myanchor;
  482. iswild:
  483.         if(myanchor=ArpAlloc(sizeof(struct MyAnchor)))
  484.         {
  485.             reg BOOL showit=TRUE;
  486.             reg LONG error;
  487.  
  488.             myanchor->APath.ap_StrLen = 255;    /* Want full path built */
  489.             myanchor->APath.ap_Flags = APF_DOWILD;
  490.             myanchor->APath.ap_BreakBits=SIGBREAKF_CTRL_C;
  491.  
  492.             error=FindFirst(pathname,&myanchor->APath);
  493.             while(!error)
  494.             {
  495.                 /* +1 because of a lattice bug */
  496.                 if(SetSignal(0L,SIGBREAKF_CTRL_E+1) & SIGBREAKF_CTRL_E)
  497.                 {
  498.                     Puts("***DIR BREAK"); showit=FALSE;
  499.                     /* myanchor->APath.ap_Flags &= ~APF_DODIR; */
  500.                 }
  501.  
  502.                 if(myanchor->APath.ap_Info.fib_DirEntryType>=0)    /* Dir */
  503.                 {
  504.                     if(all)
  505.                     {
  506.                         if(!(myanchor->APath.ap_Flags & APF_DIDDIR))
  507.                         {
  508.                             myanchor->APath.ap_Flags |= APF_DODIR;
  509.                             showit=TRUE;
  510.                         }
  511.                         myanchor->APath.ap_Flags &= ~APF_DIDDIR;
  512.                     }
  513.                 }
  514.                 else if(showit) ShowPicture(myanchor->APath.ap_Buf);
  515.                 error=FindNext(&myanchor->APath);
  516.             }
  517.  
  518.             FreeAnchorChain(&myanchor->APath);
  519.  
  520.             switch(error)
  521.             {
  522.                 case ERROR_BREAK:                _abort(); break;
  523.  
  524.                 case ERROR_OBJECT_NOT_FOUND:    Puts("File not found."); break;
  525.  
  526.                 case ERROR_BUFFER_OVERFLOW:        Puts("Path too long!"); break;
  527.  
  528.                 case ERROR_NO_MORE_ENTRIES:        break;    /* Normal termination */
  529.  
  530.                 default:    Printf("IO error %ld!\n",error); break;
  531.             }
  532.         }
  533.         else Fail("No mem for anchor!");
  534.     }
  535.     else if(file=Open(pathname,MODE_OLDFILE))    /* Just a file ? */
  536.     {
  537.         Close(file); ShowPicture(pathname); return;
  538.     }
  539.     else    /* No wildcards, and not a file: it's a device or a directory */
  540.     {
  541.         strcpy(buf,pathname); TackOn(pathname=buf,"*");
  542.         goto iswild;    /* Not really elegant, but it works */
  543.     }
  544. }
  545.  
  546. /************************************************************************/
  547. /* Main program: parse the command line or WorkBench-args */
  548.  
  549. void ARPMain(LONG arglen,reg char *argline)
  550. {
  551.     WorkBench=(arglen==0);
  552.     emptysprite=AllocMem(20L,MEMF_CHIP|MEMF_CLEAR);
  553.  
  554.     if(!(IFFBase = OpenLibrary(IFFNAME,0L))) Fail("No iff.library!");
  555.     if(IFFBase->lib_Version < IFFVERSION)
  556.         Printf("WARNING: you have an old version of iff.library!\n");
  557.  
  558.     if(arglen)        /* From CLI */
  559.     {
  560.         char *argv[NUMARGS];        /* Filled in by GADS() */
  561.  
  562.         if(*argline != '\n')
  563.         {
  564.             if(GADS(argline,(LONG)strlen(argline),CLI_Help,argv,CLI_Template)>0)
  565.             {
  566.                 if(argv[ARG_DELAY]) delay=Atol(argv[ARG_DELAY]);
  567.                 loop     = (BOOL)argv[ARG_LOOP];
  568.                 all      = (BOOL)argv[ARG_ALL];
  569.                 nobreak  = (BOOL)argv[ARG_NOBREAK];
  570.                 overscan = (BOOL)!argv[ARG_NOOVERSCAN];
  571.                 do
  572.                 {
  573.                     reg char **pattern=(char **)argv[ARG_PATTERN];
  574.                     if(*pattern)
  575.                     {
  576.                         while(*pattern) ShowPattern(*pattern++);
  577.                     }
  578.                     else ShowPattern("*");
  579.                 } while(loop);
  580.             }
  581.             else Fail(CLI_Help);
  582.         }
  583.         else Fail(CLI_Help);
  584.     }
  585.     else    /* Called from Workbench */
  586.     {
  587.         reg struct WBStartup *startup = (struct WBStartup *)argline;
  588.         struct WBArg *arg;
  589.         reg WORD i;
  590.  
  591.         if(startup->sm_NumArgs > 1)    /* Started with some arguments */
  592.         {
  593.             arg = startup->sm_ArgList;
  594.             for(i=1; i<startup->sm_NumArgs; ++i)
  595.             {
  596.                 arg++;
  597.                 if(arg->wa_Lock) CurrentDir(arg->wa_Lock);
  598.                 else Fail("Can't lock!");
  599.                 if(arg->wa_Name && *arg->wa_Name) ShowPattern(arg->wa_Name);
  600.                 else ShowPattern("*");
  601.             }
  602.         }
  603.         else
  604.         {
  605.             WBDelay=6291456;    /* 6 seconds delay */
  606. #ifdef GERMAN
  607.             Fail("Bitte klicken Sie alle gewünschten Bild-Dateien oder Schubladen bei ge-\n"
  608.              "drückter SHIFT-Taste an, klicken Sie danach 2x auf das ShowIFF-Piktogramm.");
  609. #else
  610.             Fail("Please select all drawers and files to view while holding\n"
  611.              "down the SHIFT key, then double-click the ShowIFF icon.");
  612. #endif
  613.         }
  614.     }
  615.     WBDelay=1048576;            /* One second delay */
  616. #ifdef GERMAN
  617.     Fail("Fertig.");
  618. #else
  619.     Fail("All done.");
  620. #endif
  621.  
  622. }
  623.  
  624.